About GDI+

GDI+ is the successor to GDI, the graphics device interface included with earlier versions of Windows.

A graphics device interface, such as GDI+, allows application programmers to display information on a screen or printer without having to be concerned about the details of a particular display device. The application programmer makes calls to the provided functions and those functions in turn make the appropriate calls to specific device drivers. GDI+ insulates the application from the graphics hardware, and it is this insulation that allows developers to create device-independent applications.

Microsoft Windows GDI+ exposes a flat application programming interface (API) that consists of about 600 functions, which are implemented in Gdiplus.dll and declared in Gdiplusflat.h. Microsoft has wrapped these functions with a collection of about 40 C++ classes and the Microsoft Product Support Services will not provide support for code that calls the flat API directly.

The functions in the flat API return a status value that indicates whether the call has succeeded or not.

Documentation MSDN Documentation: GDI+

GDI+ Flat Api

Microsoft Windows GDI+ exposes a flat application programming interface (API) that consists of about 600 functions, which are implemented in Gdiplus.dll and declared in Gdiplusflat.h.

The functions in the flat API return a value of type GpStatus, identical to the Status enumeration.

Template for the examples

#define _WIN32_WINNT &h0602
#INCLUDE ONCE "AfxNova/AfxGdiPlus.bi"
#INCLUDE ONCE "AfxNova/ARGB_Colors.bi"
#INCLUDE ONCE "AfxNova/CGraphCtx.inc"
USING AfxNova

CONST IDC_GRCTX = 1001

DECLARE FUNCTION wWinMain (BYVAL hInstance AS HINSTANCE, _
                           BYVAL hPrevInstance AS HINSTANCE, _
                           BYVAL pwszCmdLine AS WSTRING PTR, _
                           BYVAL nCmdShow AS LONG) AS LONG

   END wWinMain(GetModuleHandleW(NULL), NULL, wCOMMAND(), SW_NORMAL)

' // Forward declaration
DECLARE FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

' ========================================================================================
' Put here the example code
' ========================================================================================
SUB Example_XXXX (BYVAL hdc AS HDC)
END SUB
' ========================================================================================

' ========================================================================================
' Main
' ========================================================================================
FUNCTION wWinMain (BYVAL hInstance AS HINSTANCE, _
                   BYVAL hPrevInstance AS HINSTANCE, _
                   BYVAL pwszCmdLine AS WSTRING PTR, _
                   BYVAL nCmdShow AS LONG) AS LONG

   ' // Set process DPI aware
   SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE)
   ' // Enable visual styles without including a manifest file
   AfxEnableVisualStyles

   ' // Create the main window
   DIM pWindow AS CWindow = "MyClassName"
'   pWindow.CreateOverlapped(NULL, "GDI+ CreateAdjustableArrowCap", @WndProc)
   pWindow.Create(NULL, "GDI+ CreateAdjustableArrowCap", @WndProc)
   ' // Size it by setting the wanted width and height of its client area
   pWindow.SetClientSize(400, 250)
   ' // Center the window
   pWindow.Center

   ' // Add a graphic control
   DIM pGraphCtx AS CGraphCtx = CGraphCtx(@pWindow, IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   pGraphCtx.Clear RGB_FLORALWHITE
   ' // Anchor the control
   pWindow.AnchorControl(pGraphCtx.hWindow, AFX_ANCHOR_HEIGHT_WIDTH)
   
   ' // Get the memory device context of the graphic control
   DIM hdc AS HDC = pGraphCtx.GetMemDc

   ' // Initialize GDI+
   DIM token AS ULONG_PTR = AfxGdipInit

   ' // Draw the graphics
   Example_CreateAdjustableArrowCap(hdc)

   ' // Displays the window and dispatches the Windows messages
   FUNCTION = pWindow.DoEvents(nCmdShow)

   ' // Shutdown GDI+
   AfxGdipShutdown token

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

   SELECT CASE uMsg

      ' // If an application processes this message, it should return zero to continue
      ' // creation of the window. If the application returns –1, the window is destroyed
      ' // and the CreateWindowExW function returns a NULL handle.
      CASE WM_CREATE
         AfxEnableDarkModeForWindow(hwnd)
         RETURN 0

      ' // Theme has changed
      CASE WM_THEMECHANGED
         AfxEnableDarkModeForWindow(hwnd)
         RETURN 0

      CASE WM_COMMAND
         SELECT CASE CBCTL(wParam, lParam)
            CASE IDCANCEL
               ' // If ESC key pressed, close the application by sending an WM_CLOSE message
               IF CBCTLMSG(wParam, lParam) = BN_CLICKED THEN
                  SendMessageW hwnd, WM_CLOSE, 0, 0
                  RETURN 0
               END IF
         END SELECT

        CASE WM_DESTROY
         ' // Ends the application by sending a WM_QUIT message
         PostQuitMessage(0)
         RETURN 0

   END SELECT

   ' // Default processing of Windows messages
   FUNCTION = DefWindowProcW(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================

Functions

Name Description
GdiplusStartup Initializes Microsoft Windows GDI+.
GdiplusShutdown Cleans up resources used by Windows GDI+.
GdipAlloc Allocates memory for GDI+ objects.
GdipFree Frees memory allocated for GDI+ objects.

Wrapper Functions

Name Description
AfxGdipInit Initilizes GDI+.
AfxGdipShutdown Cleans up resources used by Windows GDI+.
AfxGdipStatusStr Returns the description of a GdiPlus status code.
ObjectTypeIsValid Determines whether an element of the ObjectType enumeration represents a valid object type.

GdiplusStartup

The GdiplusStartup function initializes Microsoft Windows GDI+. Call GdiplusStartup before making any other GDI+ calls, and call GdiplusShutdown when you have finished using GDI+.

FUNCTION GdiplusStartup (BYVAL token AS ULONG_PTR PTR, BYVAL input AS CONST GdiplusStartupInput PTR, _
   BYVAL output AS GdiplusStartupOutput PTR) AS GpStatus
Parameter Description
token [out] Pointer to a ULONG_PTR that receives a token. Pass the token to GdiplusShutdown when you have finished using GDI+.
input [in] Pointer to a GdiplusStartupInput structure that contains the GDI+ version, a pointer to a debug callback function, a Boolean value that specifies whether to suppress the background thread, and a Boolean value that specifies whether to suppress external image codecs.
output [out] Pointer to a GdiplusStartupOutput structure that receives a pointer to a notification hook function and a pointer to a notification unhook function. If the SuppressBackgroundThread data member of the input parameter is FALSE, then this parameter can be NULL.

Return Value

If the function succeeds, it returns Ok, which is an element of the Status enumeration.

If the function fails, it returns one of the other elements of the Status enumeration.

Remarks

You must call GdiplusStartup before you create any GDI+ objects, and you must delete all of your GDI+ objects before you call GdiplusShutdown.

You can call GdiplusStartup on one thread and call GdiplusShutdown on another thread as long as you delete all of your GDI+ objects (or have them go out of scope) before you call GdiplusShutdown.

Do not call GdiplusStartup or GdiplusShutdown in DllMain or in any function that is called by DllMain. If you want to create a dynamic-link library (DLL) that uses GDI+, you should use one of the following techniques to initialize GDI+:

Warning For info about how to use dynamic data exchange (DDE) with GDI+, see Special CWinApp Services.

The GdiplusShutdown function cleans up resources used by Microsoft Windows GDI+. Each call to GdiplusStartup should be paired with a call to GdiplusShutdown.


GdiplusShutdown

The GdiplusShutdown function cleans up resources used by Windows GDI+. Each call to GdiplusStartup should be paired with a call to GdiplusShutdown.

SUB GdiplusShutdown (BYVAL token AS ULONG_PTR)
Parameter Description
token [in] Token returned by a previous call to GdiplusStartup.

Remarks

You must call GdiplusStartup before you create any GDI+ objects, and you must delete all of your GDI+ objects before you call GdiplusShutdown.


GdipAlloc

Allocates memory for GDI+ objects.

FUNCTION GdipAlloc (BYVAL size AS size_t) AS ANY PTR
Parameter Description
size [in] [in] Number of bytes to be allocated.

Return Value

If the function succeeds, the return value is a pointer to the allocated memory block.

If the function fails, then return value is NULL.


GdipFree

Frees memory allocated for GDI+ objects.

SUB GdipFree (BYVAL ptr AS ANY PTR)
Parameter Description
ptr [in] Pointer to the memory block to free.

ObjectTypeIsValid

The ObjectTypeIsValid function determines whether an element of the ObjectType enumeration represents a valid object type.

FUNCTION ObjectTypeIsValid (BYVAL type_ as ObjectType) AS BOOLEAN
    FUNCTION = -((type_ >= ObjectTypeMin) AND (type_ <= ObjectTypeMax))
END FUNCTION
Parameter Description
type [in] Element of the ObjectType enumeration to be tested.

Return value

If objectType is equal to ObjectTypeInvalid, this function returns FALSE.

If objectType is equal to any other element of the ObjectType enumeration, this function returns TRUE.


AfxGdipInit

Initilizes GDI+

FUNCTION AfxGdipInit () AS ULONG_PTR

Remarks

You must call AfxGdipInit before you create any GDI+ objects, and you must delete all of your GDI+ objects (or have them go out of scope) before you call AfxGdipShutdown.

You can call AfxGdipIni” on one thread and call AfxGdipShutdown”” on another thread as long as you delete all of your GDI+ objects (or have them go out of scope) before you call AfxGdipShutdown**.

Do not call AfxGdipIni or AfxGdipShutdown in DllMain or in any function that is called by DllMain. If you want to create a DLL that uses GDI+, you should use one of the following techniques to initialize GDI+:


AfxGdipShutdown

Cleans up resources used by Windows GDI+. Each call to AfxGdipInit should be paired with a call to AfxGdipShutdown.

FUNCTION AfxGdipShutdown (BYVAL token AS ULONG_PTR)
Parameter Description
token [in] Token returned by a previous call to AfxGdipInit.

You must call AfxGdipInit before you create any GDI+ objects, and you must delete all of your GDI+ objects (or have them go out of scope) before you call AfxGdipShutdown.


AfxGdipStatusStr

Returns the description of a GdiPlus status code.

PRIVATE FUNCTION AfxGdipStatusStr (BYVAL status AS GpStatus) AS DWSTRING

   DIM wszMsg AS WSTRING * 260 = "Unknown"

   SELECT CASE status
      CASE Ok                        : wszMsg = "Ok"
      CASE GenericError              : wszMsg = "Generic error"
      CASE InvalidParameter          : wszMsg = "Invalid parameter"
      CASE OutOfMemory               : wszMsg = "Out of memory"
      CASE ObjectBusy                : wszMsg = "Object busy"
      CASE InsufficientBuffer        : wszMsg = "Insufficient buffer"
      CASE NotImplemented            : wszMsg = "Not implemented"
      CASE Win32Error                : wszMsg = "Win 32 error"
      CASE WrongState                : wszMsg = "Wrong state"
      CASE Aborted                   : wszMsg = "Aborted"
      CASE FileNotFound              : wszMsg = "File not found"
      CASE ValueOverflow             : wszMsg = "Value overflow"
      CASE AccessDenied              : wszMsg = "Access denied"
      CASE UnknownImageFormat        : wszMsg = "Unknown image format"
      CASE FontFamilyNotFound        : wszMsg = "Font family not found"
      CASE FontStyleNotFound         : wszMsg = "Font style not found"
      CASE NotTrueTypeFont           : wszMsg = "Not TrueType font"
      CASE UnsupportedGdiplusVersion : wszMsg = "Unsupported GdiPlus version"
      CASE GdiplusNotInitialized     : wszMsg = "GdiPlus not initialized"
      CASE PropertyNotFound          : wszMsg = "Property not found"
      CASE PropertyNotSupported      : wszMsg = "Property not supported"
'   #IF (GDIPVER >= &H0110)
'      CASE ProfileNotFound           : wszMsg = "Profile not found"
'   #ENDIF   ' //(GDIPVER >= &H0110)
   END SELECT

   RETURN wszMsg

END FUNCTION